package org.raymond.iworks.study.orders.service.impl;

import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.raymond.iworks.apis.common.ErrorCode;
import org.raymond.iworks.apis.exception.BaseException;
import org.raymond.iworks.core.holder.CacheHolder;
import org.raymond.iworks.repository.repository.TSysUserRepository;
import org.raymond.iworks.study.orders.common.GlobalCache;
import org.raymond.iworks.study.orders.entity.*;
import org.raymond.iworks.study.orders.repository.*;
import org.raymond.iworks.study.orders.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private TProductRepository tProductRepository;
    @Autowired
    private TInventoryRepository tInventoryRepository;
    @Autowired
    private TSysUserRepository tSysUserRepository;
    @Autowired
    private TOrderItemRepository tOrderItemRepository;
    @Autowired
    private TOrderRepository tOrderRepository;

    /**
     * 1,样本:2000,平均:6,最小:0,最大:540,吞吐量:137.3/s,中位数:6,99分位:22,95分位:12 没有预热
     * 2,样本:2000,平均:7,最小:0,最大:924,吞吐量:126.3/s,中位数:6,99分位:18,95分位:12 没有预热
     * 3,样本:2000,平均:6,最小:0,最大:43,吞吐量:156.7/s,中位数:5,99分位:17,95分位:10 预热过
     * 4,样本:2000,平均:6,最小:0,最大:155,吞吐量:144.3/s,中位数:5,99分位:19,95分位:12 预热过
     * 5,样本:2000,平均:6,最小:0,最大:139,吞吐量:160.4/s,中位数:5,99分位:17,95分位:10 预热过
     */
    @Transactional(rollbackFor = Exception.class)
    public void normalImplSecKill(Long userId, Long productId, Integer num){
        if(num<=0) throw new BaseException(ErrorCode.BAD_REQUEST, "订单商品数量不能小于等于0");

        /*
        // 查询商品信息
        Optional<TProducts> optionalTProducts = tProductRepository.findById(productId);
        TProducts product = optionalTProducts.orElseThrow(()->new BaseException(ErrorCode.NOT_FOUND, "商品不存在"));
        // 生成订单
        BigDecimal decimalNum = new BigDecimal(num);
        BigDecimal itemPrice = product.getProductUnitPrice().multiply(decimalNum);
        TOrders tOrders = TOrders.builder()
                .userId(userId)
                .totalNum(num)
                .totalPrice(itemPrice)
                .build();
        tOrderRepository.save(tOrders);
        // 生成订单项
        TOrderItems tOrderItems = TOrderItems.builder()
                .orderId(tOrders.getId())
                .productId(productId)
                .productNum(num)
                .itemPrice(itemPrice)
                .productName(product.getProductName())
                .productUnitPrice(product.getProductUnitPrice())
                .build();
        tOrderItemRepository.save(tOrderItems);
         */
        // 检查库存是否足够,若足够则扣减库存
        int effect = tInventoryRepository.soldInventory(productId, num);
        if(effect<=0){
            throw new BaseException(ErrorCode.NOT_FOUND, "商品已售罄");
        }
    }

    @Override
    public void normalCancel(Long userId, Long productId) {
        int effect = tInventoryRepository.refundInventory(productId, 1);
        if(effect<=0){
            throw new BaseException(ErrorCode.NOT_FOUND, "商品已售罄");
        }
    }

    @Async
    @Transactional(rollbackFor = Exception.class)
    public void secKillOrder(Long userId, Long productId, Integer num) {
        // 查询商品信息
        Optional<TProducts> optionalTProducts = tProductRepository.findById(productId);
        TProducts product = optionalTProducts.orElseThrow(()->new BaseException(ErrorCode.NOT_FOUND, "商品不存在"));
        // 生成订单
        BigDecimal decimalNum = new BigDecimal(num);
        BigDecimal itemPrice = product.getProductUnitPrice().multiply(decimalNum);
        TOrders tOrders = TOrders.builder()
                .userId(userId)
                .totalNum(num)
                .totalPrice(itemPrice)
                .build();
        tOrderRepository.save(tOrders);
        // 生成订单项
        TOrderItems tOrderItems = TOrderItems.builder()
                .orderId(tOrders.getId())
                .productId(productId)
                .productNum(num)
                .itemPrice(itemPrice)
                .productName(product.getProductName())
                .productUnitPrice(product.getProductUnitPrice())
                .build();
        tOrderItemRepository.save(tOrderItems);
    }

    @Override
    public void secKillCancel(Long userId, Long productId) {

    }
}
